#include "WindowsPlatformMisc.h"
#include "Runtime/Utils/StringUtils.h"
namespace BattleFire
{
    WindowsGLRenderDevice WindowsGLRenderDevice::mCurrentOpenGLDevice;
    void WindowsPlatformMisc::SetThreadName(const char* name)
    {
        TCHAR Name[256]={0};
        StringUtils::ASCIIToUnicode(name,Name);
        {
            typedef HRESULT(WINAPI *SetThreadDescriptionFnPtr)(HANDLE hThread, PCWSTR lpThreadDescription);
#pragma warning( push )
#pragma warning( disable: 4191 )	// unsafe conversion from 'type of expression' to 'type required'
            static SetThreadDescriptionFnPtr RealSetThreadDescription = (SetThreadDescriptionFnPtr) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetThreadDescription");
#pragma warning( pop )

            if (RealSetThreadDescription)
            {
                RealSetThreadDescription(::GetCurrentThread(), Name);
            }
        }
        {
#if !PLATFORM_SEH_EXCEPTIONS_DISABLED
            /**
            * Code setting the thread name for use in the debugger.
            *
            * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
            */
            const uint32 MS_VC_EXCEPTION=0x406D1388;

            struct THREADNAME_INFO
            {
                uint32 dwType;		// Must be 0x1000.
                LPCSTR szName;		// Pointer to name (in user addr space).
                uint32 dwThreadID;	// Thread ID (-1=caller thread).
                uint32 dwFlags;		// Reserved for future use, must be zero.
            };

            THREADNAME_INFO ThreadNameInfo;
            ThreadNameInfo.dwType		= 0x1000;
            ThreadNameInfo.szName		= name;
            ThreadNameInfo.dwThreadID	= ::GetCurrentThreadId();
            ThreadNameInfo.dwFlags		= 0;

            __try
            {
                RaiseException( MS_VC_EXCEPTION, 0, sizeof(ThreadNameInfo)/sizeof(ULONG_PTR), (ULONG_PTR*)&ThreadNameInfo );
            }
            __except( EXCEPTION_EXECUTE_HANDLER )
            {
            }
#endif
        }
    }
}